const {
	Service
} = require('uni-cloud-router')
const config = require("../config-uni-id-member.js")
const uniID = require('uni-id')
const {
	CLOUDURL
} = require('config')

const getUniID = (context) => {
	return uniID.createInstance({
		context,
		config
	})
}

const CryptoJS = require('crypto-js')
const Base64 = require('js-base64')

const WXBizDataCrypt = require('../WXBizDataCrypt.js')

const {
	wxPubConfig
} = require("config")
const WxPubApi = require("wx-public-api");
const wxPubApi = new WxPubApi();

const dbHelper = require('db-helper')
const orderHelper = require('order-helper')
const moment = require('moment-timezone');
const dbUtil = require('db-util');
const {
	userInfo
} = require('os')

const outTimeout = 16 * 60 * 60 * 1000 //出店超时时间，出店超过此时间将扣除押金
const pricePerHour = 100 //每小时结算价1元
const oneHour = 60 * 60 * 1000 //一小时单位毫秒
const fiveMinutes = 5 * 60 * 1000
const enterPledge = 20000 //进店押金
const shareManMaxTime = 120000 //分享人保存的最大时间

const getWXPubUserOpenId = async (unionId, city) => {
	try {
		if (unionId) {
			let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
				unionId: unionId,
				city
			})
			if (wxPubUser) {
				return wxPubUser.openId
			}
		}
	} catch (e) {
		throw e
	}
}
const msgForFirstMan = (openId, member, templateID) => {
	// console.log(templateID);
	return {
		touser: openId,
		// template_id: "2nsbUXt0lw62FNSVfc3cKP9wbe1yRfRhLFEBrPWhdjM",
		template_id: templateID,
		miniprogram: {
			appid: "wx609a0a547e98415d",
			pagepath: "pagesUser/platform/my-team"
		},
		data: {
			first: {
				// value: `您的好友"${member.nickname || ('ID: ' + member.id)}"通过您的分享注册达人成功！`
				value: `您分享好友（${member.nickname || ('ID: ' + member.id)}）注册成为了达人！`
			},
			keyword1: {
				value: `${member.nickname || ('ID: ' + member.id)}`
			},
			keyword2: {
				value: moment().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
			},
			keyword3: {
				value: "微信"
			},
			remark: {
				value: "您的团队又壮大了，请再接再厉哦！"
			}
		}
	}
}

const msgForSecondMan = (openId, parent, member, templateID) => {
	return {
		touser: openId,
		template_id: templateID,
		miniprogram: {
			appid: "wx609a0a547e98415d",
			pagepath: "pagesUser/platform/my-team"
		},
		data: {
			first: {
				// value: `"${member.nickname || ('ID: ' + member.id)}"注册达人成功，成为您的二级团队成员！`
				value: `您团队的一级达人（${parent.nickname || ('ID: ' + parent.id)}）分享（${member.nickname || ('ID: ' + member.id)}）注册成为了达人！`
			},
			keyword1: {
				value: `${member.nickname || ('ID: ' + member.id)}`
			},
			keyword2: {
				value: moment().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
			},
			keyword3: {
				value: "微信"
			},
			remark: {
				value: "您的团队又壮大了，请再接再厉哦！"
			}
		}
	}
}

const msgForThirdlyMan = (openId, parent, member, templateID) => {
	return {
		touser: openId,
		template_id: templateID,
		miniprogram: {
			appid: "wx609a0a547e98415d",
			pagepath: "pagesUser/platform/my-team"
		},
		data: {
			first: {
				// value: `"${member.nickname || ('ID: ' + member.id)}"注册达人成功，成为您的二级团队成员！`
				value: `您团队的二级达人（${parent.nickname || ('ID: ' + parent.id)}）分享（${member.nickname || ('ID: ' + member.id)}）注册成为了达人！`
			},
			keyword1: {
				value: `${member.nickname || ('ID: ' + member.id)}`
			},
			keyword2: {
				value: moment().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
			},
			keyword3: {
				value: "微信"
			},
			remark: {
				value: "您的团队又壮大了，请再接再厉哦！"
			}
		}
	}
}

const sendRegisterSuccess = async (city, msg) => {
	try {
		await wxPubApi.sendTemplateMsg(city, msg);
	} catch (e) {
		throw e
	}
}

module.exports = class MemberService extends Service {
	async setupShareManId({
		memberId,
		shareManId,
		transaction
	}) {
		let member = await dbHelper.getById("uni-id-users", memberId)
		if (member.shareManInfo && Date.now() - member.shareManInfo.bindTime > shareManMaxTime) {
			await dbHelper.update("uni-id-users", {
				_id: member._id,
				shareManInfo: this.db.command.remove()
			})
			member.shareManInfo = null
		}
		var shareMan
		if (shareManId) {
			shareMan = await dbHelper.getOne("uni-id-users", {
				id: shareManId,
				role: 'member'
			})
		}
		if (!shareMan || !shareMan.shareGrade) {
			if (member.shareManInfo) {
				shareMan = await dbHelper.getById('uni-id-users', member.shareManInfo.uid)
				return {
					...member.shareManInfo,
					id: shareMan.id,
					avatar: shareMan.avatar,
					nickname: shareMan.nickname
				}
			}
			return null
		}
		await dbHelper.update("uni-id-users", {
			_id: member._id,
			shareManInfo: {
				uid: shareMan._id,
				bindTime: Date.now()
			}
		})
		return {
			id: shareMan.id,
			avatar: shareMan.avatar,
			nickname: shareMan.nickname,
			bindTime: Date.now()
		}
	}
	async getGiftList({
		isReceived,
		receiverId,
		skuId,
		pageNum = 1,
		pageSize = 10
	}) {
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate
		try {
			let result = {
				total: 0,
				list: []
			}
			let query = {}
			if (receiverId) {
				query.receiverId = receiverId
			} else {
				if (isReceived) {
					query.receiverId = dbCmd.exists(true)
				} else if (isReceived != null && isReceived === false) {
					query.receiverId = dbCmd.exists(false)
				}
			}
			if (skuId) {
				query.skuId = skuId
			}
			let countRes = await this.db.collection("t3ds-ticket-gift")
				.where(query)
				.count()
			if (!countRes.total) {
				return result
			}
			result.total = countRes.total
			let res = await this.db.collection("t3ds-ticket-gift").aggregate()
				.match(query)
				.sort({
					receiveTime: -1,
					createTime: -1
				})
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				.lookup({
					from: "t3ds-store",
					localField: "storeId",
					foreignField: "_id",
					as: "store"
				})
				.lookup({
					from: "t3ds-mall-sku",
					localField: "skuId",
					foreignField: "_id",
					as: "sku"
				})
				.lookup({
					from: "uni-id-users",
					localField: "receiverId",
					foreignField: "_id",
					as: "member"
				})
				.lookup({
					from: "t3ds-receipts",
					let: {
						giftId: "$_id"
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$giftId', '$$giftId'])
						])))
						.sort({
							deadline: -1
						})
						.limit(1)
						.done(),
					as: 'receipt'
				})
				.end()
			res.data.forEach(item => {
				console.log('xxxxxxxxxxxx', item)
				item.storeName = item.store.length ? item.store[0].name : ''
				item.skuName = item.sku[0].length ? item.sku[0].name : ''
				if (item.receipt.length) {
					item.deadline = item.receipt[0].deadline
				}
				if (item.member.length) {
					item.receiverId = item.member[0].id
				}
				delete item.member
				delete item.receipt
				delete item.store
				delete item.sku
			})
			result.list = res.data
			return result
		} catch (e) {
			console.error(e)
			throw e
		}
	}

	async getMemberStoreInfo({
		memberId,
		storeId
	}) {
		let member = await dbHelper.getById("uni-id-users", memberId)
		if (!member) {
			throw new Error("会员不存在")
		}
		// if (!member.vipInfo) {
		// 	throw new Error("不是会员")
		// }
		let store = await dbHelper.getById("t3ds-store", storeId)
		if (!store) {
			throw new Error("门店不存在")
		}
		let vipInfo = member.vipInfo
		// if (!(vipInfo.storeVipCardInfo && vipInfo.storeVipCardInfo.expirationTime >= Date.now()) &&
		// 	!(vipInfo.merchantVipCardInfo && vipInfo.merchantVipCardInfo.expirationTime >= Date.now())) {
		// 	throw new Error("会员卡已过期")
		// }
		let canConsumeService = false
		if (vipInfo && store.joinFreePlan) {
			if (vipInfo.storeVipCardInfo && vipInfo.storeVipCardInfo.settlementWay === 'time' &&
				vipInfo.storeVipCardInfo.expirationTime >= Date.now()) {
				canConsumeService = true
			}
			if (vipInfo.merchantVipCardInfo && vipInfo.merchantVipCardInfo.expirationTime >= Date.now()) {
				canConsumeService = true
			}
		}

		if (canConsumeService) {
			let serviceRemainTimes = member.serviceRemainTimes || {}
			var remainTimes = serviceRemainTimes[store._id]
			if (remainTimes == undefined) {
				remainTimes = store.serviceTimes
			}
			member.remainTimes = remainTimes
		}
		member.canConsumeService = canConsumeService
		delete member.serviceRemainTimes
		delete member.wx_openid
		delete member.wx_unionid
		delete member.token

		let chargeoffRecords = await dbHelper.getPage("t3ds-vip-chargeoff-record", 1, 10, {
			storeId,
			memberId
		}, [{
			field: 'enterInfo.time',
			order: 'desc'
		}])
		const dbCmd = this.db.command
		var record = await dbHelper.getOne("t3ds-vip-chargeoff-record", {
			storeId: store._id,
			memberId: memberId,
			needSettle: true,
			settleTime: dbCmd.exists(false),
			enterInfo: dbCmd.exists(true),
			outInfo: dbCmd.exists(false)
		})
		if (record && record.enterInfo.time + outTimeout > Date.now()) {
			member.isEnter = false
		} else {
			member.isEnter = true
		}
		return {
			...member,
			serviceContent: store.serviceContent,
			records: chargeoffRecords.list
		}
	}

	async getVipChargeoffRecords({
		storeId,
		pageNum = 1,
		pageSize = 10,
		startTime,
		endTime
	}) {
		let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
		let isBoss = user.role.some(role => {
			return role === 'boss'
		})
		let dbCmd = this.db.command
		let query = []
		let store
		if (storeId) {
			store = await dbHelper.getById("t3ds-store", storeId)
			if (!store) {
				throw new Error("门店不存在")
			}
			if (store && store.uid !== user._id && store.employeeIds.indexOf(user._id) === -1) {
				throw new Error("无权限")
			}
			query.push({
				storeId
			})
		} else {
			if (isBoss) {
				let storeRes = await this.db.collection("t3ds-store").where({
					uid: user._id
				}).field({
					_id: true
				}).get()
				query.push({
					storeId: dbCmd.in(storeRes.data.map(item => {
						return item._id
					}))
				})
			} else {
				let storeRes = await this.db.collection("t3ds-store").where({
					employeeIds: user._id
				}).field({
					_id: true
				}).get()
				query.push({
					storeId: dbCmd.in(storeRes.data.map(item => {
						return item._id
					}))
				})
			}
		}
		if (!isBoss) {
			query.push(dbCmd.or([{
				'enterInfo.employeeId': this.ctx.auth.uid
			}, {
				'outInfo.employeeId': this.ctx.auth.uid
			}]))
		}
		if (startTime) {
			query.push({
				'enterInfo.time': dbCmd.gte(startTime)
			})
		}
		if (endTime) {
			query.push({
				'enterInfo.time': dbCmd.lte(endTime)
			})
		}
		let page = await dbHelper.getPage("t3ds-vip-chargeoff-record", pageNum, pageSize, dbCmd.and(query), [{
			field: 'outInfo.time',
			order: 'desc'
		}, {
			field: 'enterInfo.time',
			order: 'desc'
		}])
		page.list.forEach(item => {
			if (item.outInfo) {
				item.pricePerHour = pricePerHour
				let time = item.outInfo.time - item.enterInfo.time
				item.totalPrice = Math.round(time / oneHour * pricePerHour)
			}
		})
		return page
	}

	async chargeoffVipCard({
		storeId,
		memberId,
		chargeoffType
	}) {
		let dbCmd = this.db.command,
			transaction
		try {
			let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			let store = await dbHelper.getById("t3ds-store", storeId)
			if (!store) {
				throw new Error("门店不存在")
			}
			if (store.uid !== user._id && store.employeeIds.indexOf(user._id) === -1) {
				throw new Error("门店不匹配")
			}
			console.log(`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}`)
			// if (!store.enableVip) {
			// 	return {
			// 		code: 500,
			// 		msg: "当前门店不支持核销会员卡"
			// 	}
			// }
			let member = await dbHelper.getById("uni-id-users", memberId)
			if (!member) {
				throw new Error("会员不存在")
			}
			let vipInfo = member.vipInfo
			if (!vipInfo) {
				return {
					code: 500,
					msg: "普通会员无法使用"
				}
			}

			if (!vipInfo.lastUseTime && vipInfo.lastUseTime < Date.now() - fiveMinutes) {
				return {
					code: 500,
					msg: "二维码已失效，请重新获取"
				}
			}

			if (!(vipInfo.storeVipCardInfo && vipInfo.storeVipCardInfo.expirationTime >= Date.now()) &&
				!(vipInfo.merchantVipCardInfo && vipInfo.merchantVipCardInfo.expirationTime >= Date.now())) {
				throw new Error("会员卡已过期")
			}
			let storeVipCard, merchantVipCard
			if (vipInfo.storeVipCardInfo) {
				storeVipCard = await dbHelper.getById("t3ds-vip-card", vipInfo.storeVipCardInfo.cardId)
			}
			if (vipInfo.merchantVipCardInfo) {
				merchantVipCard = await dbHelper.getById("t3ds-vip-card", vipInfo.merchantVipCardInfo.cardId)
			}
			let isNormalStoreVip = vipInfo.storeVipCardInfo && vipInfo.storeVipCardInfo.expirationTime >= Date
				.now()
			let isSuperVip = isNormalStoreVip && storeVipCard && storeVipCard.settlementWay === 'time'
			let isMerchantVip = vipInfo.merchantVipCardInfo && vipInfo.merchantVipCardInfo.expirationTime >=
				Date.now()
			// if (!(storeVipCard && (!storeVipCard.storeIds.length || storeVipCard.storeIds.indexOf(store._id) > -
			// 		1)) &&
			// 	!(merchantVipCard && (!merchantVipCard.storeIds.length || merchantVipCard.storeIds.indexOf(store
			// 			._id) > -1) &&
			// 		(!merchantVipCard.serviceCategoryIds.length || merchantVipCard.serviceCategoryIds.indexOf(
			// 				store.serviceCategoryId) >
			// 			-1))) {
			// 	throw new Error("会员卡不支持在本店使用")
			// }

			if (chargeoffType === 'consumeService') {
				if (!store.joinFreePlan) {
					throw new Error("本店还不是联盟商家，无法核销")
				}
				if (!isSuperVip && !isMerchantVip) {
					return {
						code: 500,
						msg: "非至尊年卡用户和非商家服务卡用户无法使用"
					}
				}
				if (!isSuperVip) {
					if (merchantVipCard.serviceCategoryIds.length && merchantVipCard.serviceCategoryIds.indexOf(
							store.categoryId) === -1) {
						throw new Error("当前会员卡不支持在本店使用")
					}
				}
				if (store.limitServiceTimes !== -1) {
					if (store.limitServiceTimes <= 0) {
						throw new Error("服务次数已达上限")
					}
				}
				let serviceRemainTimes = member.serviceRemainTimes || {}
				let remainTimes = serviceRemainTimes[store._id]
				if (remainTimes == undefined) {
					remainTimes = store.serviceTimes
				}
				if (remainTimes <= 0) {
					throw new Error('服务次数已使用完了')
				}
				transaction = await this.db.startTransaction()
				let record = {
					memberId: memberId,
					memberNickname: member.nickname,
					storeId: store._id,
					storeName: store.name,
					enterInfo: {
						time: Date.now(),
						employeeId: user._id,
						employeeName: user.username
					},
					needSettle: false,
					type: 'consumeService',
					remainServiceTimes: remainTimes - 1
				}
				await dbHelper.insert("t3ds-vip-chargeoff-record", record, transaction)
				serviceRemainTimes[store._id] = remainTimes - 1
				await dbHelper.update("uni-id-users", {
					_id: member._id,
					serviceRemainTimes
				}, transaction)
				if (store.limitServiceTimes !== -1) {
					await dbHelper.update("t3ds-store", {
						_id: store._id,
						limitServiceTimes: dbCmd.inc(-1)
					}, transaction)
				}
				console.log(
					`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}，剩余服务次数：${remainTimes - 1}`
				)
				await transaction.commit()
				return record
			}
			if (!isNormalStoreVip) {
				throw new Error("商家服务卡用户不能在门店使用")
			}
			if (!isSuperVip && storeVipCard.storeIds.length && storeVipCard.storeIds.indexOf(storeId) === -1) {
				throw new Error("单店会员卡不支持在本店使用")
			}
			if (isSuperVip) {
				console.log(`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}`)
				var record = await dbHelper.getOne("t3ds-vip-chargeoff-record", {
					storeId: store._id,
					memberId: memberId,
					needSettle: true,
					settleTime: dbCmd.exists(false),
					enterInfo: dbCmd.exists(true),
					outInfo: dbCmd.exists(false)
				})
				if (record) {
					record = await dbHelper.getById("t3ds-vip-chargeoff-record", record._id, transaction)
				}
				var account = await dbHelper.getOne("t3ds-account", {
					userId: member._id
				})
				if (record && record.enterInfo.time + outTimeout > Date.now()) {
					// 存在进店记录并且未超时的情况下视为会员出店
					transaction = await this.db.startTransaction()
					await transaction.collection('t3ds-vip-chargeoff-record').doc(record._id)
						.update({
							outInfo: {
								time: Date.now(),
								employeeId: user._id,
								employeeName: user.username
							}
						})
					// 出店退押金
					account = await dbHelper.getById("t3ds-account", account._id, transaction)
					await transaction.collection("t3ds-account").doc(account._id).update({
						balance: dbCmd.inc(enterPledge),
						frozen: dbCmd.inc(-enterPledge)
					})
					await dbHelper.insert("t3ds-account-log", {
						userId: member._id,
						accountId: account._id,
						income: enterPledge,
						tradeType: 11,
						settled: true,
						createTime: Date.now(),
						balance: account.balance + enterPledge
					})
					await transaction.commit()
					console.log(`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}，会员出店退还押金`)
					record.outInfo = {
						time: Date.now(),
						employeeId: user._id,
						employeeName: user.username
					}
					return record
				} else {
					if (account.balance < enterPledge) {
						throw new Error('余额不足，请先充值')
					}
					let record = {
						memberId: memberId,
						memberNickname: member.nickname,
						storeId: store._id,
						storeName: store.name,
						enterInfo: {
							time: Date.now(),
							employeeId: user._id,
							employeeName: user.username
						},
						needSettle: true,
						type: 'enter',
					}
					transaction = await this.db.startTransaction()
					await dbHelper.insert("t3ds-vip-chargeoff-record", record, transaction)
					//进店交押金
					await transaction.collection("t3ds-account").doc(account._id).update({
						balance: dbCmd.inc(-enterPledge),
						frozen: dbCmd.inc(enterPledge)
					})
					await dbHelper.insert("t3ds-account-log", {
						userId: member._id,
						accountId: account._id,
						income: enterPledge,
						tradeType: -4,
						settled: true,
						createTime: Date.now(),
						balance: account.balance - enterPledge
					})
					await transaction.commit()
					console.log(
						`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}，会员进店，已交押金${enterPledge}元`
					)
					return record
				}
			} else {
				transaction = await this.db.startTransaction()
				let record = {
					memberId: memberId,
					memberNickname: member.nickname,
					storeId: store._id,
					storeName: store.name,
					enterInfo: {
						time: Date.now(),
						employeeId: user._id,
						employeeName: user.username
					},
					needSettle: false,
					type: 'enter',
				}
				await dbHelper.insert("t3ds-vip-chargeoff-record", record, transaction)
				await transaction.commit()
				console.log(`会员核销，商家名：${store.name}，会员id: ${memberId}，核销类型：${chargeoffType}，会员进店，无需交押金`)
				return record
			}
		} catch (e) {
			if (transaction) {
				await transaction.rollback()
			}
			console.error(e)
			// console.error(`会员核销遇到错误，事务回滚，memberId=${memberId}`, e);
			throw e
		}
	}

	async exchangeGoods({
		codeId,
		userId
	}) {
		let transaction = await this.db.startTransaction()
		try {
			let exchangeCode = await dbHelper.getById("t3ds-goods-exchange", codeId, transaction)
			if (!exchangeCode) {
				await transaction.commit()
				return {
					code: 500,
					msg: '兑换码不存在'
				}
			}
			if (exchangeCode.status !== 'delivered') {
				await transaction.commit()
				return {
					code: 500,
					msg: '兑换码无效'
				}
			}
			if (exchangeCode.convertibilityID) {
				if (exchangeCode.convertibilityID != userId) {
					return {
						code: 500,
						msg: '无权限兑换'
					}
				}
			}

			let sku = await dbHelper.getById("t3ds-mall-sku", exchangeCode.skuId)
			if (!sku) {
				await transaction.commit()
				return {
					code: 500,
					msg: "商品规格不存在"
				}
			}
			let goods = await dbHelper.getById("t3ds-mall-goods", sku.goods_id)
			if (!goods) {
				await transaction.commit()
				return {
					code: 500,
					msg: "商品不存在"
				}
			}
			let result = {
				goods: goods,
				sku: sku
			}
			let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			if (goods.type === 'ticket') {
				let item = {
					goods_id: goods._id,
					goods_name: goods.name,
					goods_thumb: goods.thumb,
					sku_id: sku._id,
					sku_name: sku.name,
					price: sku.price,
					settlement_price: exchangeCode.settlementPrice,
					count: 1,
					discountsForVip: 0
				}
				let order = {
					total_fee: 0,
					discounts_for_vip: 0,
					payment_fee: 0,
					pay_time: Date.now(),
					pay_type: 'wxpay',
					user_id: user._id,
					user_nickname: user.nickname,
					user_phone: user.mobile,
					platform: "mp-weixin",
					status: 3,
					items: [item],
					use_balance: false,
					create_time: Date.now(),
					create_by: user.nickname,
					type: 'goods'
				}
				await dbHelper.insert("t3ds-order", order, transaction)
				let deadline;
				if (sku.time_limit) {
					if (sku.time_limit.type === 'relative') {
						deadline = moment().tz("Asia/Shanghai").add(sku.time_limit.value, 'days').hour(23)
							.minute(59).second(59).toDate()
							.getTime() //Date.now() + sku.time_limit.value * 24 * 60 * 60 * 1000
					} else {
						deadline = moment.tz(sku.time_limit.value, "Asia/Shanghai").hour(23).minute(59).second(
							59).toDate().getTime();
					}
				} else {
					deadline = moment().tz("Asia/Shanghai").add(30, 'days').hour(23).minute(59).second(59)
						.toDate().getTime();
				}
				let totalCount = await dbHelper.getCount("t3ds-ticket-code", {})
				let ticketCode = {
					goodsName: `${goods.name}|${sku.name}`,
					goodsPrice: item.price,
					settlementPrice: item.settlement_price,
					orderId: order._id,
					deadline: deadline,
					status: 0,
					sn: `10${user.id}${totalCount + 1}`,
					source: 'exchange',
					exchangeCodeId: exchangeCode._id
				}
				await transaction.collection("t3ds-ticket-code").add(ticketCode)
				result.order = order
			} else if (goods.type === 'vipCard') {
				let vipCard = await dbHelper.getById("t3ds-vip-card", sku.vip_card_id, transaction)
				await orderHelper.updateUserVipInfo(vipCard, user, transaction)
				result.vipCard = vipCard
			}
			await dbHelper.update("t3ds-goods-exchange", {
				_id: exchangeCode._id,
				exchangeTime: Date.now(),
				memberId: user._id,
				memberName: user.nickname,
				status: 'exchanged',
			}, transaction)

			await transaction.commit()
			return {
				code: 200,
				result: result
			}
		} catch (e) {
			if (transaction) {
				await transaction.rollback()
			}
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async exchangeGoodsAdmin({
		codeId,
		userId
	}) {
		let transaction = await this.db.startTransaction()
		try {
			let exchangeCode = await dbHelper.getById("t3ds-goods-exchange", codeId, transaction)
			if (!exchangeCode) {
				await transaction.commit()
				return {
					code: 500,
					msg: '兑换码不存在'
				}
			}
			if (exchangeCode.status !== 'delivered') {
				await transaction.commit()
				return {
					code: 500,
					msg: '兑换码无效'
				}
			}
			let user = await dbHelper.getOne("uni-id-users", {
				id: parseInt(userId)
			})
			if (!user) {
				await transaction.commit()
				return {
					code: 500,
					msg: "用户不存在"
				}
			}
			let sku = await dbHelper.getById("t3ds-mall-sku", exchangeCode.skuId)
			if (!sku) {
				await transaction.commit()
				return {
					code: 500,
					msg: "商品规格不存在"
				}
			}
			let goods = await dbHelper.getById("t3ds-mall-goods", sku.goods_id)
			if (!goods) {
				await transaction.commit()
				return {
					code: 500,
					msg: "商品不存在"
				}
			}
			let result = {
				goods: goods,
				sku: sku
			}
			if (goods.type === 'ticket') {
				let item = {
					goods_id: goods._id,
					goods_name: goods.name,
					goods_thumb: goods.thumb,
					sku_id: sku._id,
					sku_name: sku.name,
					price: sku.price,
					settlement_price: exchangeCode.settlementPrice,
					count: 1,
					discountsForVip: 0
				}
				let order = {
					total_fee: 0,
					discounts_for_vip: 0,
					payment_fee: 0,
					pay_time: Date.now(),
					pay_type: 'wxpay',
					user_id: user._id,
					user_nickname: user.nickname,
					user_phone: user.mobile,
					platform: "mp-weixin",
					status: 3,
					items: [item],
					use_balance: false,
					create_time: Date.now(),
					create_by: user.nickname,
					type: 'goods'
				}
				await dbHelper.insert("t3ds-order", order, transaction)
				let deadline;
				if (sku.time_limit) {
					if (sku.time_limit.type === 'relative') {
						deadline = moment().tz("Asia/Shanghai").add(sku.time_limit.value, 'days').hour(23)
							.minute(59).second(59).toDate()
							.getTime() //Date.now() + sku.time_limit.value * 24 * 60 * 60 * 1000
					} else {
						deadline = moment.tz(sku.time_limit.value, "Asia/Shanghai").hour(23).minute(59).second(
							59).toDate().getTime();
					}
				} else {
					deadline = moment().tz("Asia/Shanghai").add(30, 'days').hour(23).minute(59).second(59)
						.toDate().getTime();
				}
				let totalCount = await dbHelper.getCount("t3ds-ticket-code", {})
				let ticketCode = {
					goodsName: `${goods.name}|${sku.name}`,
					goodsPrice: item.price,
					settlementPrice: item.settlement_price,
					orderId: order._id,
					deadline: deadline,
					status: 0,
					sn: `10${user.id}${totalCount + 1}`,
					source: 'exchange',
					exchangeCodeId: exchangeCode._id
				}
				await transaction.collection("t3ds-ticket-code").add(ticketCode)
				result.order = order
			} else if (goods.type === 'vipCard') {
				let vipCard = await dbHelper.getById("t3ds-vip-card", sku.vip_card_id, transaction)
				await orderHelper.updateUserVipInfo(vipCard, user, transaction)
				result.vipCard = vipCard
			}
			await dbHelper.update("t3ds-goods-exchange", {
				_id: exchangeCode._id,
				exchangeTime: Date.now(),
				memberId: user._id,
				memberName: user.nickname,
				status: 'exchanged',
			}, transaction)

			await transaction.commit()
			return {
				code: 200,
				result: result
			}
		} catch (e) {
			if (transaction) {
				await transaction.rollback()
			}
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async registerShareExpert({
		codeId,
		codeCity
	}) {
		let transaction
		try {
			let member, relation, code, parentRelation;
			code = await dbHelper.getById("t3ds-share-expert-code", codeId);
			// let user = await dbHelper.getById("uni-id-users", code.userId)
			if (!code) {
				return {
					code: 500,
					msg: "邀请码不存在"
				}
			}
			if (code.receiverTime) {
				return {
					code: 500,
					msg: "邀请码已失效"
				}
			}
			if (!code.grade) {
				let parentUser = await dbHelper.getById("uni-id-users", code.userId)
				if (!parentUser.shareGrade) {
					return {
						code: 500,
						msg: "邀请码已失效"
					}
				}
			}
			member = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			if (member.shareGrade == 4) {
				return {
					code: 500,
					msg: "您已是超级达人，无须再次注册"
				}
			}
			// let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
			// 	// city: user.city,
			// 	city: codeCity,
			// 	unionId: member.wx_unionid
			// })
			// if (!wxPubUser) {
			// 	return {
			// 		code: 501,
			// 		msg: "您还没有关注公众号"
			// 	}
			// }
			if (code.grade && member.shareGrade > 3) {
				return {
					code: 500,
					msg: "您已是达人，无须再次注册"
				}
			}
			relation = await dbHelper.getOne("t3ds-share-expert-relation", {
				userId: member._id
			});
			if (!code.grade && relation && !relation.temporary && member.shareGrade < 4) {
				return {
					code: 500,
					msg: "您已是达人，无须再次注册"
				}
			}
			if (!code.super) {
				parentRelation = await dbHelper.getOne("t3ds-share-expert-relation", {
					userId: code.userId
				})
				if (parentRelation) {
					let parent = await dbUtil.getById({
						collection: "uni-id-users",
						id: code.userId
					})
					if ((!member.shareGrade || member.shareCode < 4) && parent.shareGrade > 4) {
						return {
							code: 500,
							msg: "无法注册，请联系客服！"
						}
					}
				}
			}

			transaction = await this.db.startTransaction()
			if (relation) {
				if (parentRelation) {
					relation.parentId = parentRelation._id;
				}
				relation.temporary = false;
				relation.updateBy = member.nickname;
				relation.updateTime = Date.now();
				await dbHelper.update("t3ds-share-expert-relation", relation, transaction);
			} else {
				relation = {
					userId: member._id,
					temporary: false,
					createBy: member.nickname,
					createTime: Date.now()
				};
				if (parentRelation) {
					relation.parentId = parentRelation._id;
				}
				await dbHelper.insert("t3ds-share-expert-relation", relation, transaction);
			}
			if (code.super || (code.grade && code.grade >= 4)) {
				code.receiverTime = Date.now();
				code.receiverId = member._id;
				code.receiverName = member.nickname;
				code.receiverPhone = member.mobile;
				code.updateTime = Date.now();
				code.updateBy = member.nickname;
				await dbHelper.update("t3ds-share-expert-code", code, transaction);
			}
			if (!member.shareGrade || member.shareGrade < 4) {
				await dbHelper.update("uni-id-users", {
					_id: member._id,
					shareGrade: code.grade || (code.super ? 4 : 1),
					city: codeCity,
					registerShareExpertTime: Date.now(),
					latestIncomeTime: Date.now(), //最近一次获得收益的时间，默认是达人注册时间
					lastNoticeDate: -1
				}, transaction);
			}

			//判断是否升级
			if (parentRelation) {
				let parent = await dbHelper.getById("uni-id-users", code.userId)
				let childCount = await dbHelper.getCount("t3ds-share-expert-relation", {
					parentId: parentRelation._id,
					temporary: false
				})
				if (parent.shareGrade === 1 && childCount >= 15) {
					//初级升中级
					await dbHelper.update("uni-id-users", {
						_id: code.userId,
						shareGrade: 2
					}, transaction);
				} else if (parent.shareGrade === 2 && childCount >= 35) {
					//中级升高级
					await dbHelper.update("uni-id-users", {
						_id: code.userId,
						shareGrade: 3
					}, transaction);
				}
				// 获取模板ID
				let temp = await dbHelper.getOne('t3ds-region', {
					'city.value': codeCity
				})
				let tempId = temp.templateMsgs.find(item => {
					return item.templateName === '达人注册成功通知'
				}).templateID
				try {
					let firstManOpenId = await getWXPubUserOpenId(parent.wx_unionid, codeCity)
					if (firstManOpenId) {
						await sendRegisterSuccess(codeCity, msgForFirstMan(firstManOpenId, member, tempId));

						if (parentRelation.parentId) { // 分享者存在上级
							let secondManRelation = await dbHelper.getById("t3ds-share-expert-relation",
								parentRelation.parentId) // 获取分享者上级
							let secondMan = await dbHelper.getById("uni-id-users", secondManRelation.userId)
							let secondManOpenId = await getWXPubUserOpenId(secondMan.wx_unionid, codeCity)
							if (secondManOpenId) {
								await sendRegisterSuccess(codeCity, msgForSecondMan(secondManOpenId, parent,
									member, tempId));

								if (secondManRelation.parentId) { // 分享者存在上上级
									let thirdlyManRelation = await dbHelper.getById(
										"t3ds-share-expert-relation", secondManRelation.parentId
									) // 获取分享者上上级
									let thirdlyMan = await dbHelper.getById("uni-id-users", thirdlyManRelation
										.userId)
									let thirdlyManOpenId = await getWXPubUserOpenId(thirdlyMan.wx_unionid,
										codeCity)
									if (thirdlyManOpenId) {
										await sendRegisterSuccess(codeCity, msgForThirdlyMan(thirdlyManOpenId,
											parent, member, tempId));
									}
								}

							}
						}
					}
				} catch (e) {
					console.error('发送达人注册通知遇到错误', e)
				}
			}

			await transaction.commit();

			return {
				code: 200,
				result: true
			}
		} catch (e) {
			console.log("注册达人遇到错误", e);
			if (transaction) {
				await transaction.rollback();
			}
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async getAccount({
		codeId
	}) {
		try {
			let code = await dbHelper.getById("t3ds-share-expert-code", codeId)
			let {
				city: codeCity
			} = await dbHelper.getById("uni-id-users", code.userId)
			let {
				wxPubConfig: {
					account
				},
				name
			} = await dbHelper.getOne("t3ds-region", {
				'city.value': codeCity
			})
			return {
				code: 200,
				result: {
					account: account,
					city: codeCity,
					name
				}
			}
		} catch (e) {
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async getMyPosters(currentCityCode) {
		try {
			let posters = await dbHelper.getList("t3ds-share-expert-poster", {})
			let list = []
			for (var i = 0; i < posters.length; i++) {
				let poster = posters[i]
				let cache = await dbHelper.getOne("file-cache", {
					srcUrl: `poster_${this.ctx.auth.uid}_${poster._id}_${ currentCityCode }.jpg`
				})
				console.log(cache);
				list.push({
					templateId: poster._id,
					templateUrl: poster.url,
					posterUrl: cache ?
						`${CLOUDURL}/getTecentImgUrl?fileID=${cache.fileID}` : ''
				})
			}
			return {
				code: 200,
				result: list
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async getMyShareCode() {
		try {
			let member = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			if (member.shareGrade === 0) {
				return {
					code: 500,
					msg: "普通用户没有推广权限，请先联系客服升级为达人！"
				}
			}
			var code = await dbHelper.getOne("t3ds-share-expert-code", {
				userId: member._id
			})
			if (!code) {
				code = {
					userId: member._id,
					createTime: Date.now(),
					createBy: member.nickname
				}
				await dbHelper.insert("t3ds-share-expert-code", code);
			}
			return {
				code: 200,
				result: code
			}
		} catch (e) {
			console.log("获取我的邀请码遇到错误", e);
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	async getMemberOrders({
		memberId,
		status,
		type,
		pageNum = 1,
		pageSize = 20
	}) {
		try {
			let member = await dbHelper.getById('uni-id-users', memberId)
			if (!member) {
				return {
					code: 500,
					msg: "会员不存在"
				}
			}
			let dbCmd = this.db.command
			if (type) {
				let query;
				if (type === 'personal') {
					query = dbCmd.and({
						userId: member._id
					}, dbCmd.or({
						buyManId: member._id
					}, {
						shareReward: dbCmd.exists(true)
					}))
				} else if (type === 'team') {
					query = dbCmd.and({
						userId: member._id
					}, dbCmd.or({
						firstBrokerage: dbCmd.exists(true)
					}, {
						secondBrokerage: dbCmd.exists(true)
					}, {
						firstShareBrokerage: dbCmd.exists(true)
					}, {
						secondShareBrokerage: dbCmd.exists(true)
					}))
				} else {
					query = {
						userId: member._id
					}
				}
				let countRes = await this.db.collection("t3ds-share-order")
					.where(query).count();
				let list = [];
				if (countRes.total) {
					let orderRes = await this.db.collection("t3ds-share-order")
						.where(query)
						.orderBy("createTime", "desc")
						.skip((pageNum - 1) * pageSize)
						.limit(pageSize)
						.get();
					list = orderRes.data;

					for (var i = 0; i < list.length; i++) {
						let t = list[i];
						let originalOrderRes = await this.db.collection("t3ds-order").doc(t.orderId)
							.field({
								_id: false
							})
							.get();
						if (originalOrderRes.data.length) {
							let originalOrder = originalOrderRes.data[0];
							list[i] = Object.assign(t, originalOrder);
						}

						let buyMan = await dbHelper.getById("uni-id-users", t.user_id)
						t.buyManGrade = buyMan.shareGrade
						t.user_id = buyMan.id
						t.user_nickname = buyMan.nickname || '微信用户'

						if (t.shareManId) {
							let shareMan = await dbHelper.getOne("uni-id-users", {
								id: parseInt(t.shareManId),
								role: 'member'
							});
							if (shareMan) {
								t.shareManId = shareMan.id
								t.shareMan = shareMan.nickname || '微信用户';
								t.shareManPhone = shareMan.mobile;
								t.shareManGrade = shareMan.shareGrade;
							}
						}
					}
				}
				return {
					code: 200,
					result: {
						total: countRes.total,
						list: list
					}
				}
			} else {
				let query = {
					user_id: member._id,
					status: status
				}
				let countRes = await this.db.collection("t3ds-order")
					.where(query).count();
				var list = [];
				if (countRes.total) {
					let orderRes = await this.db.collection("t3ds-order")
						.where(query)
						.orderBy("create_time", "desc")
						.skip((pageNum - 1) * pageSize)
						.limit(pageSize)
						.get();
					list = orderRes.data;
				}
				return {
					code: 200,
					result: {
						total: countRes.total,
						list: list
					}
				}
			}
		} catch (e) {
			console.error(e)
			uniCloud.logger.error("加载我的订单遇到错误", e);
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	async getMemberTeamList({
		memberId,
		level,
		pageNum,
		pageSize,
		temporary,
		userId,
		keyword
	}) {
		try {
			let member = await dbHelper.getById("uni-id-users", memberId);
			if (!member) {
				return {
					code: 500,
					msg: "会员不存在"
				}
			}
			let relation = await dbHelper.getOne("t3ds-share-expert-relation", {
				userId: member._id
			})
			if (!relation) {
				return {
					code: 200,
					result: {
						total: 0,
						list: []
					}
				}
			}

			pageNum = pageNum || 1;
			pageSize = pageSize || 20;
			let result = {
				code: 200,
				result: {
					total: 0,
					list: []
				}
			}

			let searchMember
			if (keyword && /\d+/.test(keyword)) {
				searchMember = await dbHelper.getOne("uni-id-users", {
					id: parseInt(keyword)
				})
			}

			let dbCmd = this.db.command
			let collection = this.db.collection("t3ds-share-expert-relation");
			if (userId) {
				// 查询指定一级成员的一级成员，即我的二级成员
				let firstManRelation = await dbHelper.getOne("t3ds-share-expert-relation", {
					parentId: relation._id,
					userId: userId + ''
				})
				if (!firstManRelation) {
					// 指定用户不是我的一级成员，无权查看
					return {
						code: 500,
						msg: "无权限"
					}
				}
				let query = {
					parentId: firstManRelation._id
				};
				if (searchMember) {
					query.userId = searchMember._id
				}
				// if (temporary !== undefined || temporary !== null) {
				// 	query.temporary = temporary;
				// }
				let count = await dbHelper.getCount("t3ds-share-expert-relation", query);
				if (count) {
					result.result.total = count;
					let relationRes = await collection.where(query)
						.orderBy("createTime", "desc")
						.skip((pageNum - 1) * pageSize)
						.limit(pageSize)
						.get();
					result.result.list = relationRes.data;
				}
			} else {
				let query = {
					parentId: relation._id
				}
				if (temporary !== undefined || temporary !== null) {
					query.temporary = temporary;
				}
				if (level != 2) {
					// 获取一级团队
					if (searchMember) {
						query.userId = searchMember._id
					}
					let count = await dbHelper.getCount("t3ds-share-expert-relation", query);
					if (count) {
						result.result.total = count;
						let relationRes = await collection.where(query)
							.orderBy("createTime", "desc")
							.skip((pageNum - 1) * pageSize)
							.limit(pageSize)
							.get();
						result.result.list = relationRes.data;
					}
				} else {
					// 获取二级团队
					if (searchMember) {
						let countRes = await collection.aggregate()
							.match(query)
							.lookup({
								from: "t3ds-share-expert-relation",
								foreignField: "parentId",
								localField: "_id",
								as: "children"
							})
							.unwind('$children')
							.match({
								'children.userId': searchMember._id
							})
							.count("total")
							.end();
						if (!countRes.data.length) {
							return result;
						}
						result.result.total = countRes.data[0].total;
						let relationRes = await collection.aggregate()
							.match(query)
							.lookup({
								from: "t3ds-share-expert-relation",
								foreignField: "parentId",
								localField: "_id",
								as: "children"
							})
							.unwind('$children')
							.match({
								'children.userId': searchMember._id
							})
							.replaceRoot({
								newRoot: '$children'
							})
							.sort({
								createTime: -1
							})
							.skip((pageNum - 1) * pageSize)
							.limit(pageSize)
							.end();
						result.result.list = relationRes.data;
					} else {
						let countRes = await collection.aggregate()
							.match(query)
							.lookup({
								from: "t3ds-share-expert-relation",
								foreignField: "parentId",
								localField: "_id",
								as: "children"
							})
							.unwind('$children')
							.count("total")
							.end();
						if (!countRes.data.length) {
							return result;
						}
						result.result.total = countRes.data[0].total;
						let relationRes = await collection.aggregate()
							.match(query)
							.lookup({
								from: "t3ds-share-expert-relation",
								foreignField: "parentId",
								localField: "_id",
								as: "children"
							})
							.unwind('$children')
							.replaceRoot({
								newRoot: '$children'
							})
							.sort({
								createTime: -1
							})
							.skip((pageNum - 1) * pageSize)
							.limit(pageSize)
							.end();
						result.result.list = relationRes.data;
					}
				}
			}
			if (result.result.total) {
				let dbCmd = this.db.command
				let $ = dbCmd.aggregate
				let userIds = result.result.list.map(item => {
					return item.userId;
				});
				let users = await dbHelper.getList("uni-id-users", {
					_id: dbCmd.in(userIds)
				});
				let userMap = {};
				users.forEach(item => {
					userMap[item._id] = item;
				})
				let relationIds = result.result.list.map(item => {
					return item._id;
				});
				let firstCountRes = await this.db.collection("t3ds-share-expert-relation").aggregate()
					.match({
						parentId: dbCmd.in(relationIds)
					})
					.group({
						_id: "$parentId",
						count: $.sum(1)
					})
					.end();
				let countMap = {};
				if (firstCountRes.data && firstCountRes.data.length) {
					firstCountRes.data.forEach(item => {
						countMap[item._id] = item.count;
					})
				}
				let secondCountRes = await collection.aggregate()
					.match({
						parentId: dbCmd.in(relationIds)
					})
					.lookup({
						from: "t3ds-share-expert-relation",
						foreignField: "parentId",
						localField: "_id",
						as: "children"
					})
					.unwind('$children')
					.group({
						_id: "$parentId",
						count: $.sum(1)
					})
					.end();
				if (secondCountRes.data && secondCountRes.data.length) {
					secondCountRes.data.forEach(item => {
						if (countMap[item._id]) {
							countMap[item._id] = countMap[item._id] + item.count;
						}
					})
				}

				let parentMemberMap = {};
				let parentRelationMap = {};
				if (level == 2) {
					let parentIds = result.result.list.map(item => {
						return item.parentId;
					});
					let parentRelations = await collection.where({
							"_id": dbCmd.in(parentIds)
						})
						.get();
					let parentUserIds = parentRelations.data.map(item => {
						parentRelationMap[item._id] = item;
						return item.userId;
					})
					let members = await dbHelper.getList("uni-id-users", {
						_id: dbCmd.in(parentUserIds)
					});
					members.forEach(item => {
						parentMemberMap[item._id] = item;
					})
				}
				for (var i = 0; i < result.result.list.length; i++) {
					let t = result.result.list[i];
					if (level == 2 || userId) {
						let {
							id,
							nickname,
							avatar
						} = userMap[t.userId];
						t.member = {
							id,
							nickname,
							avatar
						};
					} else {
						let {
							id,
							nickname,
							mobile,
							avatar
						} = userMap[t.userId];
						t.member = {
							id,
							nickname,
							mobile,
							avatar
						};
					}
					t.grade = userMap[t.userId].shareGrade;

					t.teamCount = countMap[t._id] || 0;

					if (level == 2) {
						let parentMember = parentMemberMap[parentRelationMap[t.parentId].userId];
						t.parent = {
							nickname: parentMember.nickname,
							id: parentMember.id,
							phone: parentMember.mobile
						}
					}
				}
			}
			return result
		} catch (e) {
			console.error("查询我的团队遇到错误", e);
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	async updateUserInfoByTt({
		userInfo
	}) {
		try {
			await this.db.collection("uni-id-users").doc(this.ctx.auth.uid)
				.update({
					nickname: userInfo.nickName,
					avatar: userInfo.avatarUrl,
					gender: userInfo.gender
				})
			let res = await this.getMemberInfo({
				memberId: this.ctx.auth.uid,
				payType: "tt"
			})
			return res
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async updateUserInfoByWXData({
		code,
		wxUserInfo
	}) {
		try {
			let session = await getUniID(this.ctx.context).code2SessionWeixin({
				code
			})
			if (session.code) {
				return {
					code: 500,
					msg: session.message
				}
			}
			let pc = new WXBizDataCrypt(config['mp-weixin'].oauth.weixin.appid, session.sessionKey)
			let info = pc.decryptData(wxUserInfo.encryptedData, wxUserInfo.iv)
			console.log("解密之后的微信用户数据", info)
			await this.db.collection("uni-id-users").doc(this.ctx.auth.uid)
				.update({
					nickname: info.nickName,
					avatar: info.avatarUrl,
					gender: info.gender
				})
			let res = await this.getMemberInfo({
				memberId: this.ctx.auth.uid
			})
			return res
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}



	async ttlogin(code, role) {
		const params = {
			"appid": "ttc46fb2d25b563c6601",
			"secret": "c20890c691b533751d181434a9887c5319cd5157",
			"code": code
		}
		let ttres = await uniCloud.httpclient.request(
			"https://developer.toutiao.com/api/apps/v2/jscode2session", {
				method: 'POST',
				data: params,
				contentType: 'json', // 指定以application/json发送data内的数据
				dataType: 'json' // 指定返回值为json格式，自动进行parse
			})
		let transaction = await this.db
		const ttunionid = transaction.collection("uni-id-users").where({
			"tt_unionid": ttres.data.data.unionid
		}).get();
		return ttunionid.then(res => {
			if (res.data.length == 0) {
				const userInfo = {
					"tt_unionid": ttres.data.data.unionid,
					"tt_openid": {
						"mp-tt": ttres.data.data.openid
					},
					"role": ["member"]
				}
				const uid = transaction.collection("uni-id-users").add(userInfo)
				uid.then(res => {
					userInfo.uid = res.id
				})
				return userInfo
			} else {
				const userInfo = res.data[0]
				userInfo.uid = userInfo._id
				return userInfo
			}
		})
	}




	async loginByToutiao({
		code,
		ttMobileData
	}) {
		let loginRes
		try {
			loginRes = await this.ttlogin(code)
			console.log(loginRes)
			// if (loginRes.err_no !== 0) {
			// 	throw new Error(loginRes.message)
			// }
		} catch (e) {
			throw e
		}
		let transaction = await this.db.startTransaction()
		try {
			// let key = CryptoJS.enc.Base64.parse(loginRes.data.session_key)
			// let ivInfo = CryptoJS.enc.Base64.parse(ttMobileData.iv)
			// let decrypt = CryptoJS.AES.decrypt(ttMobileData.encryptedData, key, {
			// 	iv: ivInfo,
			// 	mode: CryptoJS.mode.CBC,
			// 	padding: CryptoJS.pad.Pkcs7
			// })
			// let info = JSON.parse(Base64.decode(CryptoJS.enc.Base64.stringify(decrypt)))
			// transaction.collection("uni-id-users").doc(loginRes.uid).update(userInfo)
			// Object.assign(userInfo, loginRes.userInfo)

			// transaction.insert

			let userInfo = {
				id: loginRes.id
			}



			if (!userInfo.id) {
				var sysConfig = await dbHelper.getOne("t3ds-system-config", {
					key: 'userNo'
				})
				if (!sysConfig) {
					await dbHelper.insert("t3ds-system-config", {
						"key": "userNo",
						"value": 1
					}, transaction)
					userInfo.id = 1
				} else {
					sysConfig = await dbHelper.getById("t3ds-system-config", sysConfig._id, transaction)
					userInfo.id = sysConfig.value + 1
					await transaction.collection("t3ds-system-config").doc(sysConfig._id)
						.update({
							value: userInfo.id
						})
				}
				await transaction.collection("uni-id-users").doc(loginRes.uid)
					.update({
						id: userInfo.id,
						shareGrade: 0,
						creditScore: 30, // 信誉积分

					})
			}
			// 创建现金账户
			var account = await dbHelper.getOne("t3ds-account", {
				userId: loginRes.uid
			})
			if (!account) {
				account = {
					userId: loginRes.uid,
					total: 0,
					balance: 0,
					settle: 0,
					frozen: 0,
					createTime: Date.now(),
					createBy: userInfo.nickname
				}
				await dbHelper.insert("t3ds-account", account, transaction)
			}

			userInfo.account = account
			userInfo.mobile = loginRes.mobile
			const token = uniID.createToken({
				"uid": loginRes.uid
			})
			this.db.collection('uni-id-users').doc(loginRes.uid).update({
				"token": [token.token]
			})
			await transaction.commit()
			Object.assign(userInfo, loginRes)
			loginRes.token = token.token
			loginRes.tokenExpired = token.tokenExpired
			console.log(loginRes)

			return {
				tokenInfo: {
					token: loginRes.token,
					expired: loginRes.tokenExpired
				},
				userInfo
			}
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			if (loginRes && loginRes.userInfo && !loginRes.userInfo.id) {
				await this.db.collection("uni-id-users").doc(loginRes.uid).remove()
			}
			if (loginRes && loginRes.token) {
				await uniID.logout(loginRes.token)
			}
			throw e
		}
	}

	async loginByWeixin({
		code,
		wxMobileData
	}) {
		console.log('+++++++++loginByWeixin')
		let loginRes
		try {
			loginRes = await getUniID(this.ctx.context).loginByWeixin({
				code,
				role: ['member']
			})
			if (loginRes.code !== 0) {
				throw new Error(loginRes.message)
			}
			console.log('----------', loginRes)
		} catch (e) {
			console.log('----------', e)
			throw e
		}
		console.log('+++++++++', loginRes)
		let transaction = await this.db.startTransaction()
		try {
			let key = CryptoJS.enc.Base64.parse(loginRes.sessionKey)
			let ivInfo = CryptoJS.enc.Base64.parse(wxMobileData.iv)
			let decrypt = CryptoJS.AES.decrypt(wxMobileData.encryptedData, key, {
				iv: ivInfo,
				mode: CryptoJS.mode.CBC,
				padding: CryptoJS.pad.Pkcs7
			})
			let info = JSON.parse(Base64.decode(CryptoJS.enc.Base64.stringify(decrypt)))
			if (!info.phoneNumber) {
				throw new Error("手机号缺失")
			}
			let userInfo = {
				mobile: info.phoneNumber,
				countryCode: info.countryCode
			}
			await transaction.collection("uni-id-users").doc(loginRes.uid).update(userInfo)
			Object.assign(userInfo, loginRes.userInfo)
			if (!userInfo.id) {
				var sysConfig = await dbHelper.getOne("t3ds-system-config", {
					key: 'userNo'
				})
				if (!sysConfig) {
					await dbHelper.insert("t3ds-system-config", {
						"key": "userNo",
						"value": 1
					}, transaction)
					userInfo.id = 1
				} else {
					sysConfig = await dbHelper.getById("t3ds-system-config", sysConfig._id, transaction)
					userInfo.id = sysConfig.value + 1
					await transaction.collection("t3ds-system-config").doc(sysConfig._id)
						.update({
							value: userInfo.id
						})
				}
				await transaction.collection("uni-id-users").doc(loginRes.uid)
					.update({
						id: userInfo.id,
						shareGrade: 0,
						creditScore: 30 // 信誉积分
					})
			}
			// 创建现金账户
			var account = await dbHelper.getOne("t3ds-account", {
				userId: loginRes.uid
			})
			if (!account) {
				account = {
					userId: loginRes.uid,
					total: 0,
					balance: 0,
					settle: 0,
					frozen: 0,
					createTime: Date.now(),
					createBy: userInfo.nickname
				}
				await dbHelper.insert("t3ds-account", account, transaction)
			}
			userInfo.account = account
			await transaction.commit()
			return {
				tokenInfo: {
					token: loginRes.token,
					expired: loginRes.tokenExpired
				},
				userInfo
			}
		} catch (e) {
			console.error(e)
			await transaction.rollback()
			if (loginRes && loginRes.userInfo && !loginRes.userInfo.id) {
				await this.db.collection("uni-id-users").doc(loginRes.uid).remove()
			}
			if (loginRes && loginRes.token) {
				await uniID.logout(loginRes.token)
			}
			throw e
		}
	}

	async updateMobileWithWXData({
		uid,
		code,
		encryptedData,
		iv
	}) {
		let session = await uniID.code2SessionWeixin({
			code
		})
		if (session.code) {
			return {
				code: 500,
				msg: session.message
			}
		}
		let key = CryptoJS.enc.Base64.parse(session.sessionKey)
		let ivInfo = CryptoJS.enc.Base64.parse(iv)
		let decrypt = CryptoJS.AES.decrypt(encryptedData, key, {
			iv: ivInfo,
			mode: CryptoJS.mode.CBC,
			padding: CryptoJS.pad.Pkcs7
		})
		let info = JSON.parse(Base64.decode(CryptoJS.enc.Base64.stringify(decrypt)))
		const res = await uniID.updateUser({
			uid: uid,
			mobile: info.phoneNumber,
			countryCode: info.countryCode
		})
		return {
			code: 200,
			result: info.phoneNumber
		}
	}

	async loginWithPwd({
		username,
		password
	}) {
		const res = await uniID.login({
			username,
			password,
			needPermission: false
		})
		if (res.code) {
			return {
				code: 500,
				msg: res.msg
			}
		}
		await this.checkToken(res.token, {
			needPermission: false,
			needUserInfo: false
		})
		// 账户信息
		let account = await dbHelper.getOne("t3ds-account", {
			userId: res.userInfo._id
		})
		res.userInfo.account = account
		return {
			code: 200,
			result: {
				tokenInfo: {
					token: res.token,
					expired: res.tokenExpired
				},
				userInfo: res.userInfo
			}
		}
	}

	async checkToken(token) {
		const auth = await getUniID(this.ctx.context).checkToken(token, {
			needPermission: true,
			needUserInfo: false
		})
		if (auth.code) {
			// 校验失败，抛出错误信息
			this.ctx.throw('TOKEN_INVALID', `${auth.message}，${auth.code}`)
		}
		this.ctx.auth = auth // 设置当前请求的 auth 对象
	}

	async getMemberInfo({
		memberId,
		currentCityCode,
		payType
	}) {
		try {
			let member = await dbHelper.getById("uni-id-users", memberId)
			if (!member) {
				return {
					code: 500,
					msg: "会员不存在"
				}
			}
			if (member.role.indexOf('member') === -1) {
				return {
					code: 500,
					msg: '非法操作'
				}
			}
			if (member.shareManInfo) {
				if (member.shareGrade > 0 || Date.now() - member.shareManInfo.bindTime > shareManMaxTime) {
					await this.db.collection("uni-id-users").doc(member._id).update({
						shareManInfo: this.db.command.remove()
					})
					delete member.shareManInfo
				} else {
					let shareMan = await dbHelper.getById("uni-id-users", member.shareManInfo.uid)
					member.shareManInfo.avatar = shareMan.avatar
					member.shareManInfo.nickname = shareMan.nickname
					member.shareManInfo.id = shareMan.id
				}
			}
			let account = await dbHelper.getOne("t3ds-account", {
				userId: member._id
			})

			// 查询个人总收益
			var personalTotalIncome = 0;
			let collection = this.db.collection("t3ds-account-log");
			let $ = this.db.command.aggregate;
			let personalIncomeRes = await collection.aggregate()
				.match({
					accountId: account._id,
					tradeType: this.db.command.in([1, 2])
				})
				.group({
					_id: '$accountId',
					total: $.sum('$income')
				})
				.end();
			if (personalIncomeRes.data.length) {
				personalTotalIncome = personalIncomeRes.data[0].total;
			}
			var teamTotalIncome = 0;
			let teamIncomeRes = await collection.aggregate()
				.match({
					accountId: account._id,
					tradeType: this.db.command.in([3, 4, 7, 8])
				})
				.group({
					_id: '$accountId',
					total: $.sum('$income')
				})
				.end();
			if (teamIncomeRes.data.length) {
				teamTotalIncome = teamIncomeRes.data[0].total;
			}

			// 查询团队人数
			var teamCount = 0;
			let relation = await dbHelper.getOne("t3ds-share-expert-relation", {
				userId: member._id
			})
			if (relation) {
				let count = await dbHelper.getCount("t3ds-share-expert-relation", {
					parentId: relation._id
				})
				teamCount += count;
				let firstRelations = await dbHelper.getList("t3ds-share-expert-relation", {
					parentId: relation._id
				})
				if (firstRelations.length) {
					let ids = firstRelations.map(item => {
						return item._id;
					})
					let secondCount = await dbHelper.getCount("t3ds-share-expert-relation", {
						parentId: this.db.command.in(ids)
					})
					teamCount += secondCount;
				}
			}

			//订单数量
			let orderCount = await dbHelper.getCount("t3ds-share-order", {
				userId: member._id
			})

			//总提现
			let withdrawRes = await this.db.collection("t3ds-withdraw-apply").aggregate()
				.match({
					userId: member._id,
					status: "PASSED"
				})
				.group({
					_id: "$userId",
					total: $.sum("$fee")
				})
				.end()
			if (withdrawRes.data.length) {
				member.withdrawTotal = withdrawRes.data[0].total
			}

			// 查询用户是否关注了公众号
			var isWxPubUser = false;
			if (member.wx_unionid) {
				let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
					unionId: member.wx_unionid,
					city: currentCityCode
				})
				if (wxPubUser) {
					isWxPubUser = true;
				}
			}

			member.account = account

			if (member.mobile) {
				member.mobile = member.mobile.substring(0, 3) + '****' + member.mobile.substring(7)
			}

			Object.assign(member, {
				teamCount,
				teamTotalIncome,
				personalTotalIncome,
				isWxPubUser,
				orderCount
			})
			delete member.token
			delete member.realname_auth

			return {
				code: 200,
				result: member
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}
	async getUserWxGzh(_id) {
		const userinfo = await this.db.collection("uni-id-users").where({
			_id: _id
		}).get()
		try {
			userinfo.data[0].wx_openid.mp_weixin_gzh
			return {
				code: 200,
				result: true
			}
		} catch (e) {
			return {
				code: 200,
				result: false
			}
		}
	}
	async refreshVipQrcode() {
		try {
			let userInfoRes = await this.db.collection("uni-id-users").doc(this.ctx.auth.uid)
				.field({
					vipInfo: true
				})
				.get()
			let userInfo = userInfoRes.data[0]
			if (userInfo.vipInfo) {
				userInfo.vipInfo.lastUseTime = Date.now()
				await this.db.collection("uni-id-users").doc(this.ctx.auth.uid)
					.update({
						vipInfo: userInfo.vipInfo
					})
			}
			return {
				code: 200
			}
		} catch (e) {
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	async getMyMotorcade({
		pageNum,
		pageSize,
		userLocation
	}) {
		try {
			const db = this.db
			const dbCmd = this.db.command
			const $ = dbCmd.aggregate

			let result = {
				total: 0,
				list: []
			}

			let res = await db.collection("t3ds-subscribe-motorcade")
				.aggregate()
				// .geoNear({
				// 	near: new db.Geo.Point(userLocation.longitude, userLocation.latitude),
				// 	query: {
				// 		status: dbCmd.neq(-1)
				// 	},
				// 	spherical: true,
				// 	distanceField: 'distance'
				// })
				.lookup({
					from: 't3ds-order',
					let: {
						motorcadeId: '$_id',
						userId: this.ctx.auth.uid
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$motorcadeId', '$$motorcadeId']),
							$.eq(['$user_id', '$$userId'])
						])))
						.done(),
					as: 'orderRes',
				})
				.addFields({
					orderResLen: $.size('$orderRes')
				})
				.match({
					orderResLen: dbCmd.gt(0)
				})
				.unwind('$orderRes')
				.match(dbCmd.expr(
					dbCmd.or(
						// dbCmd.eq(['$orderRes.status', 1]),
						dbCmd.eq(['$orderRes.status', 2]),
						dbCmd.eq(['$orderRes.status', 4]),
						dbCmd.eq(['$orderRes.status', 5]),
						dbCmd.and(
							dbCmd.eq(['$orderRes.status', 3]),
							dbCmd.gt(['$endTime', Date.now()])
						)
					)
				))
				.match({
					['orderRes.items.' + 0 + '.start_time']: dbCmd.gt(Date.now())
				})
				.count('total')
				.end()
			if (!res.data.length || !res.data[0].total) {
				return {
					code: 200,
					result
				}
			}
			result.total = res.data[0].total
			let {
				data
			} = await db.collection("t3ds-subscribe-motorcade")
				.aggregate()
				// .geoNear({
				// 	near: new db.Geo.Point(userLocation.longitude, userLocation.latitude),
				// 	query: {
				// 		status: dbCmd.neq(-1)
				// 	},
				// 	spherical: true,
				// 	distanceField: 'distance'
				// })
				.lookup({
					from: 't3ds-order',
					let: {
						motorcadeId: '$_id',
						userId: this.ctx.auth.uid
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.and([
							$.eq(['$motorcadeId', '$$motorcadeId']),
							$.eq(['$user_id', '$$userId'])
						])))
						.done(),
					as: 'orderRes',
				})
				.unwind('$orderRes')
				.match(dbCmd.expr(
					dbCmd.or(
						// dbCmd.eq(['$orderRes.status', 1]),
						dbCmd.eq(['$orderRes.status', 2]),
						dbCmd.eq(['$orderRes.status', 4]),
						dbCmd.eq(['$orderRes.status', 5]),
						dbCmd.and(
							dbCmd.eq(['$orderRes.status', 3]),
							dbCmd.gt(['$endTime', Date.now()])
						)
					)
				))
				.match({
					['orderRes.items.' + 0 + '.start_time']: dbCmd.gt(Date.now())
				})
				.sort({
					// distance: 1,
					startTime: -1
				})
				.skip((pageNum - 1) * pageSize)
				.limit(pageSize)
				// .lookup({
				// 	from: 't3ds-order',
				// 	let: {
				// 		motorcadeId: '$_id',
				// 		userId: this.ctx.auth.uid
				// 	},
				// 	pipeline: $.pipeline()
				// 		.match(dbCmd.expr($.and([
				// 			$.eq(['$motorcadeId', '$$motorcadeId']),
				// 			$.eq(['$user_id', '$$userId'])
				// 		])))
				// 		.done(),
				// 	as: 'orderRes',
				// })
				// .addFields({
				// 	orderResLen: $.size('$orderRes')
				// })
				// .match({
				// 	orderResLen: dbCmd.gt(0)
				// })
				// .unwind('$orderRes')
				// .match(dbCmd.expr(
				// 	dbCmd.or(
				// 		dbCmd.eq(['$orderRes.status', 1]),
				// 		dbCmd.eq(['$orderRes.status', 2]),
				// 		dbCmd.eq(['$orderRes.status', 4]),
				// 		dbCmd.eq(['$orderRes.status', 5]),
				// 		dbCmd.and(
				// 			dbCmd.eq(['$orderRes.status', 3]),
				// 			dbCmd.gt(['$endTime', Date.now()])
				// 		)
				// 	)
				// ))
				// .match({
				// 	['orderRes.items.' + 0 + '.start_time']: dbCmd.gt(Date.now())
				// })
				.addFields({
					playersCount: $.sum(['$currentFemaleCount', '$currentMaleCount']),
				})
				// .addFields({
				// 	// distance: '$distance',
				// 	startTime: '$startTime',
				// 	endTime: '$endTime',
				// 	costPerPerson: '$costPerPerson',
				// 	thumbnail: '$thumbnail',
				// 	name: '$name',
				// 	needCount: $.cond({
				// 		if: '$allowGetOn',
				// 		then: $.subtract(["$maxPlayers", "$playersCount"]),
				// 		else: $.subtract(["$minPlayers", "$playersCount"])
				// 	}),
				// 	deadline: $.subtract(["$startTime", Date.now()]),
				// 	storeName: '$storeName',
				// 	roomName: '$roomName',
				// 	storeId: '$storeId',
				// 	allowGetOn: '$allowGetOn'
				// })
				.project({
					name: 1,
					thumbnail: 1,
					storeName: 1,
					roomName: 1,
					startTime: 1,
					endTime: 1,
					costPerPerson: 1,
					roomId: 1,
					status: 1,
					needCount: $.cond({
						if: $.lt(["$playersCount", "$minPlayers"]),
						then: $.subtract(["$minPlayers", "$playersCount"]),
						else: 0
					})
				})
				.end()
			console.log("data: ", data);
			result.list = data

			return {
				code: 200,
				result
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				result: e
			}
		}
	}

	async getMyCollect({
		user_id,
		collectType,
		pageNum,
		pageSize,
		userLocation
	}) {
		try {
			const db = this.db
			const dbCmd = this.db.command
			const $ = dbCmd.aggregate

			let userRes = await dbHelper.getById("uni-id-users", user_id)
			let where = {
				userId: userRes.id
			}
			if (collectType) {
				where.type = collectType
			}

			let result = {
				total: 0,
				list: []
			}
			if (collectType) {
				if (collectType === 'motorcade') {
					where.motorcadeStartTime = dbCmd.gt(Date.now())
					let res = await db.collection('t3ds-collect')
						.aggregate()
						.match(where)
						.sort({
							date: -1
						})
						.lookup({
							from: "t3ds-subscribe-motorcade",
							localField: "collectId",
							foreignField: "_id",
							as: "motorcadeRes"
						})
						.unwind('$motorcadeRes')
						.replaceRoot({
							newRoot: '$motorcadeRes'
						})
						.count('total')
						.end()
					result.total = res.data[0].total
					if (!result.total) return {
						code: 200,
						result
					}

					let res1 = await db.collection('t3ds-collect')
						.aggregate()
						.match(where)
						.sort({
							date: -1
						})
						.lookup({
							from: "t3ds-subscribe-motorcade",
							localField: "collectId",
							foreignField: "_id",
							as: "motorcadeRes"
						})
						.unwind('$motorcadeRes')
						.replaceRoot({
							newRoot: '$motorcadeRes'
						})
						.skip((pageNum - 1) * pageSize)
						.limit(pageSize)
						.end()
					result.list = res1.data
				}

				if (collectType === 'script') {
					let res = await db.collection('t3ds-collect')
						.aggregate()
						.match(where)
						.sort({
							date: -1
						})
						.lookup({
							from: "t3ds-script",
							localField: "collectId",
							foreignField: "_id",
							as: "scriptRes"
						})
						.unwind('$scriptRes')
						.replaceRoot({
							newRoot: '$scriptRes'
						})
						.count('total')
						.end()
					result.total = res.data[0].total
					if (!result.total) return {
						code: 200,
						result
					}

					let res1 = await db.collection('t3ds-collect')
						.aggregate()
						.match(where)
						.sort({
							date: -1
						})
						.lookup({
							from: "t3ds-script",
							localField: "collectId",
							foreignField: "_id",
							as: "scriptRes"
						})
						.unwind('$scriptRes')
						.replaceRoot({
							newRoot: '$scriptRes'
						})
						.skip((pageNum - 1) * pageSize)
						.limit(pageSize)
						.end()
					result.list = res1.data

					result.list.forEach(item => {
						let tags = []
						if (item.storyTags && item.storyTags.length) {
							tags.push(item.storyTags[0])
						}
						if (item.classTags && item.classTags.length) {
							tags.push(item.classTags[0])
							if (item.classTags.length > 1) {
								tags.push(item.classTags[1])
							}
						}
						item.tags = tags
					})
				}

				if (collectType === 'store') {
					let collectRes = []
					collectRes = await this.db.collection("t3ds-collect")
						.aggregate()
						.match(where)
						.sort({
							date: -1
						})
						.end()
					console.log("collectRes: ", collectRes.data);

					result.total = collectRes.data.length
					let collectArr = collectRes.data.map(item => item.collectId)

					let res = []
					if (userLocation) {
						res = await db.collection("t3ds-store").aggregate().geoNear({
								near: new db.Geo.Point(userLocation.longitude, userLocation.latitude),
								query: {
									_id: dbCmd.in(collectArr)
								},
								spherical: true,
								distanceField: 'distance'
							})
							.project({
								thumbnail: $.arrayElemAt(['$photos', 0]),
								name: 1,
								address: 1,
								distance: 1
							})
							.sort({
								date: -1
							})
							.skip((pageNum - 1) * pageSize)
							.limit(pageSize)
							.end()
					} else {
						res = await db.collection("t3ds-store").aggregate()
							.match({
								_id: dbCmd.in(collectArr)
							})
							.addFields({
								distance: 0
							})
							.project({
								thumbnail: $.arrayElemAt(['$photos', 0]),
								name: 1,
								address: 1,
								distance: 1
							})
							.sort({
								date: -1
							})
							.skip((pageNum - 1) * pageSize)
							.limit(pageSize)
							.end()
					}
					result.list = res.data
				}
			}

			return {
				code: 200,
				result
			}
		} catch (e) {
			return {
				code: 500,
				result: e
			}
		}
	}

	// 领取优惠券
	async receiveCoupon(couponId) {
		const transaction = await this.db.startTransaction();

		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		try {
			let couponRes = await dbHelper.getById('t3ds-coupon', couponId, transaction)
			if (couponRes.receiveDeadline <= Date.now()) throw '此优惠券已过领取截止时间'

			await transaction.collection('t3ds-coupon').doc(couponId).update({
				count: dbCmd.inc(-1)
			});

			let deadline = 0
			switch (couponRes.deadline.type) {
				case 'relative':
					deadline = Date.now() + couponRes.deadline.value * 24 * 60 * 60 * 1000
					break;
				case 'absolute':
					deadline = couponRes.deadline.value
					break;
				default:
					break;
			}
			let userRes = await dbHelper.getById('uni-id-users', this.ctx.auth.uid, transaction)
			await transaction.collection('t3ds-coupon-member').add({
				uid: this.ctx.auth.uid,
				templateId: couponRes._id,
				name: couponRes.name,
				value: couponRes.value,
				type: couponRes.type,
				goodsType: couponRes.goodsType,
				initiator: couponRes.initiator,
				validDays: couponRes.validDays,
				minOrderAmount: couponRes.minOrderAmount,
				stores: couponRes.stores,
				deadline: deadline,
				instructions: couponRes.instructions,
				used: false,
				usedTime: '',

				createTime: Date.now(),
				createBy: userRes.username,
				updateTime: Date.now(),
				updateBy: userRes.username
			})

			await transaction.commit();
			return {
				code: 200
			}
		} catch (e) {
			await transaction.rollback();
			return {
				code: 500,
				result: e
			}
		}
	}

	//修改用户的个人信息
	async updateUserinfo({
		userinfo
	}) {
		try {
			// if(userId != this.ctx.auth.uid) {
			// 	return {
			// 		code: 500,
			// 		msg: "用户只能修改自己的信息"
			// 	}
			// }
			await this.db.collection("uni-id-users").doc(this.ctx.auth.uid)
				.update(userinfo)
			return {
				code: 200,
				result: "修改成功"
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	//通过id获取用户的个人信息
	async getUserForId({
		userId
	}) {
		try {
			// let userDetail = await this.db.collection("uni-id-users")
			// 	.where({
			// 		id: userId
			// 	})
			// 	.field({
			// 		avatar: true,
			// 		nickname: true,
			// 		gender: true,
			// 		constellation: true,
			// 		declarationDating: true,
			// 		othersCanView: true
			// 	})
			// 	.get()
			let userDetail = await dbUtil.getOne({
				collection: 'uni-id-users',
				where: {
					id: userId
				},
				field: {
					avatar: true,
					nickname: true,
					gender: true,
					constellation: true,
					declarationDating: true,
					othersCanView: true
				}
			})
			if (!userDetail) {
				return {
					code: 500,
					msg: "该用户不存在"
				}
			}
			if (userDetail.othersCanView) {
				return {
					code: 200,
					result: userDetail
				}
			} else {
				return {
					code: 200,
					result: null
				}
			}
		} catch (e) {
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}
	}

	//查询礼包金额统计
	async getUserPackageSearch() {
		try {
			const db = this.db
			const dbCmd = this.db.command
			const $ = dbCmd.aggregate
			let give = await db.collection('t3ds-package-log').aggregate().match({
					uid: this.ctx.auth.uid,
					type: 1
				})
				.project({
					packageGiveAmount: 1
				})
				.group({
					total: $.sum('$packageGiveAmount')
				})
				.end()

			let topup = await db.collection('t3ds-package-log').aggregate().match({
					uid: this.ctx.auth.uid,
					type: 1
				})
				.project({
					packageTopupAmount: 1
				})
				.group({
					total: $.sum('$packageTopupAmount')
				})
				.end()

			let amount = await db.collection('t3ds-package-user').aggregate().match({
					uid: this.ctx.auth.uid,
				})
				.project({
					packageAmount: 1
				})
				.group({
					total: $.sum('$packageAmount')
				})
				.end()

			console.log(this.ctx.auth.uid)
			console.log(give)
			console.log(topup)
			console.log(amount)
			var data = {
				giveSum: give,
				topupSum: topup,
				amountSum: amount
			}
			return data
		} catch (e) {
			//TODO handle the exception
			console.error(e)
			return {
				code: 500,
				msg: e.message
			}
		}

	}
}